package com.cy.dda.service.rule.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cy.dda.comm.constant.CacheConstants;
import com.cy.dda.comm.constant.Constants;
import com.cy.dda.comm.utils.SpringContextUtils;
import com.cy.dda.dao.mapper.rule.MenuMapper;
import com.cy.dda.dao.mapper.rule.MenuRoleMapper;
import com.cy.dda.model.domain.rule.Menu;
import com.cy.dda.model.vo.rule.MenuTreeVO;
import com.cy.dda.model.vo.rule.MenuVO;
import com.cy.dda.service.BaseService;
import com.cy.dda.service.rule.RuleService;

/**
 * 权限管理 RuleService
 *
 * @author: tanyilin
 * @create: 2018年11月9日 上午10:18:17
 */
@Service
public class RuleServiceImpl extends BaseService implements RuleService {

	@Autowired
	private MenuMapper menuMapper;
	@Autowired
	private MenuRoleMapper menuRoleMapper;
	
	@Override
	@Cacheable(value = CacheConstants.CACHE_RULE_ROLE)
	public List<Menu> selectAllMenuInCache() {
		//查询全部菜单
		List<Menu> menus = menuMapper.selectAll();
		return menus;
	}

	@Override
	@Cacheable(value = CacheConstants.CACHE_RULE_ROLE)
	public List<Long> selectAllMenuByRoleIdInCache(Long roleId) {
		//根据roleId查询该角色所拥有的全部权限菜单id
		List<Long> ids = menuRoleMapper.selectAllMenuByRoleId(roleId);
		return ids;
	}

	@Override
	@Cacheable(value = CacheConstants.CACHE_RULE_ROLE)
	public List<MenuVO> selectLeftMenusInCahce(Long roleId) {
		//查询后台左侧菜单栏
		//查询role所拥有的左侧菜单列表
		List<Menu> list = menuMapper.selectMenuByRoleId(roleId, Constants.ADMININTRATOR);
		//再构建左侧菜单结构
		List<MenuVO> result = new ArrayList<>();
		list.stream().filter(m -> Integer.valueOf(1).equals(m.getLevel())).forEach(m -> {
			MenuVO menuVO = new MenuVO();
			menuVO.setIcon(m.getIcon());
			menuVO.setName(m.getName());
			menuVO.setPath(m.getPath());
			menuVO.setChildren(new ArrayList<>());
			
			//遍历下级菜单
			list.stream().filter(menu -> m.getId().equals(menu.getParentId())).forEach(menu -> {
				MenuVO child = new MenuVO();
				child.setIcon(menu.getIcon());
				child.setName(menu.getName());
				child.setPath(menu.getPath());
				
				//把下级菜单添加进Children里
				menuVO.getChildren().add(child);
			});
			
			//把一级菜单添加进结果列表里
			result.add(menuVO);
		});
		
		return result;
	}

	@Override
	@Cacheable(value = CacheConstants.CACHE_RULE_ROLE)
	public List<MenuTreeVO> selectMenuTreeInCache(Long roleId) {
		//查询后台权限菜单树状图
		//根据roleId查询该角色所拥有的全部权限菜单id
		List<Long> ids = SpringContextUtils.getBean(RuleService.class).selectAllMenuByRoleIdInCache(roleId);
		//查询所有菜单
    	List<Menu> list = menuMapper.selectAll();
    	//构建菜单树
    	List<MenuTreeVO> result = new ArrayList<>();
    	list.stream().filter(m1 -> Integer.valueOf(1).equals(m1.getLevel())).forEach(m1 -> {
    		//一级菜单
    		MenuTreeVO first = new MenuTreeVO();
    		first.setId(m1.getId());
    		first.setName(m1.getName());
    		first.setChecked(ids.contains(m1.getId()));
    		first.setChildren(new ArrayList<>());
    		
    		list.stream().filter(m2 -> m1.getId().equals(m2.getParentId())).forEach(m2 -> {
    			//二级菜单
    			MenuTreeVO second = new MenuTreeVO();
    			second.setId(m2.getId());
    			second.setName(m2.getName());
    			second.setChecked(ids.contains(m2.getId()));
    			second.setChildren(new ArrayList<>());
    			
    			list.stream().filter(m3 -> m2.getId().equals(m3.getParentId())).forEach(m3 -> {
    				//三级菜单
    				MenuTreeVO three = new MenuTreeVO();
    				three.setId(m3.getId());
    				three.setName(m3.getName());
    				three.setChecked(ids.contains(m3.getId()));
    				
    				//将三级菜单添加到二级菜单的Children里
    				second.getChildren().add(three);
    			});
    			
    			//将二级菜单添加到一级菜单的Children里
    			first.getChildren().add(second);
    		});
    		
    		//将一级菜单添加到结果列表里
    		result.add(first);
    	});
    	
		return result;
	}

	@Override
	@Transactional
	@CacheEvict(value = CacheConstants.CACHE_RULE_ROLE, allEntries = true, beforeInvocation = true)
	public void doAuthorization(Long roleId, List<Long> menuIds) {
		//给角色授权，先新增新的权限菜单关系，再根据更新时间去删除比现在时间小的数据（即被删掉的部分权限菜单）
		Date time = new Date();
		menuRoleMapper.insertBatch(roleId, menuIds, time);
		menuRoleMapper.deleteByUpdateTime(roleId, time);
	}

}
